﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;

namespace Retrofit.Input
{
    public delegate bool GamePadButtonEvent(Buttons button);
    public delegate bool GamePadTriggerEvent(GamePadTriggers triggers);
    public delegate bool GamePadThumbstickEvent(GamePadThumbSticks thumbSticks);

    /// <summary>
    /// This class manages a single player's gamepad.
    /// </summary>
    public class GamePadManager
    {
        private PlayerIndex m_player;
        private GamePadState m_currentGamePadState;
        private GamePadState m_previousGamePadState;

        public event GamePadButtonEvent ButtonUp;
        public event GamePadButtonEvent ButtonDown;
        public event GamePadButtonEvent ButtonHeld;
        public event GamePadTriggerEvent Triggers;
        public event GamePadThumbstickEvent Thumbsticks;

        public PlayerIndex Player
        {
            get { return m_player; }
            set { m_player = value; }
        }

        public GamePadState CurrentGamePadState
        {
            get { return m_currentGamePadState; }
            set { m_currentGamePadState = value; }
        }

        public GamePadState PreviousGamePadState
        {
            get { return m_previousGamePadState; }
            set { m_previousGamePadState = value; }
        }

        public GamePadManager(PlayerIndex player)
        {
            player = m_player;
        }

        public void OnButtonDown(Buttons button)
        {
            if(ButtonDown !=null)
            {
                ButtonDown(button);
            }
        }

        public void OnButtonUp(Buttons button)
        {
            if (ButtonUp != null)
            {
                ButtonUp(button);
            }
        }

        public void OnButtonHeld(Buttons button)
        {
            if (ButtonHeld != null)
            {
                ButtonHeld(button);
            }
        }

        public void OnThumbsticks(GamePadThumbSticks thumbSticks)
        {
            if (Thumbsticks != null)
            {
                Thumbsticks(thumbSticks);
            }
        }

        public void OnTriggers(GamePadTriggers triggers)
        {
            if (Triggers != null)
            {
                Triggers(triggers);
            }
        }

        public bool IsNewButtonPressed(Buttons button)
        {
            return m_currentGamePadState.IsButtonDown(button) && m_previousGamePadState.IsButtonUp(button);
        }

        public bool IsNewButtonReleased(Buttons button)
        {
            return m_currentGamePadState.IsButtonUp(button) && m_previousGamePadState.IsButtonDown(button);
        }

        public bool IsButtonPressed(Buttons button)
        {
            return m_currentGamePadState.IsButtonUp(button);
        }

        public void Update()
        {
            m_previousGamePadState = m_currentGamePadState;
            m_currentGamePadState = GamePad.GetState(m_player);

            #region ButtonDown
            // A Button.
            if (IsNewButtonPressed(Buttons.A))
            {
                OnButtonDown(Buttons.A);
            }

            // B Button.
            if (IsNewButtonPressed(Buttons.B))
            {
                OnButtonDown(Buttons.B);
            }

            // X Button.
            if (IsNewButtonPressed(Buttons.X))
            {
                OnButtonDown(Buttons.X);
            }

            // Y Button.
            if (IsNewButtonPressed(Buttons.Y))
            {
                OnButtonDown(Buttons.Y);
            }

            // Start Button.
            if (IsNewButtonPressed(Buttons.Start))
            {
                OnButtonDown(Buttons.Start);
            }

            // Back Button.
            if (IsNewButtonPressed(Buttons.Back))
            {
                OnButtonDown(Buttons.Back);
            }

            // Big Button.
            if (IsNewButtonPressed(Buttons.BigButton))
            {
                OnButtonDown(Buttons.BigButton);
            }

            // DPadDown Buttons
            if (IsNewButtonPressed(Buttons.DPadDown))
            {
                OnButtonDown(Buttons.DPadDown);
            }

         
            if (IsNewButtonPressed(Buttons.DPadUp))
            {
                OnButtonDown(Buttons.DPadUp);
            }

       
            if (IsNewButtonPressed(Buttons.DPadLeft))
            {
                OnButtonDown(Buttons.DPadLeft);
            }

            if (IsNewButtonPressed(Buttons.DPadRight))
            {
                OnButtonDown(Buttons.DPadRight);
            }

            //LeftThumbstick buttons.
            if (IsNewButtonPressed(Buttons.LeftThumbstickDown))
            {
                OnButtonDown(Buttons.LeftThumbstickDown);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.LeftThumbstickUp))
            {
                OnButtonDown(Buttons.LeftThumbstickUp);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.LeftThumbstickLeft))
            {
                OnButtonDown(Buttons.LeftThumbstickLeft);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.LeftThumbstickRight))
            {
                OnButtonDown(Buttons.LeftThumbstickRight);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.LeftThumbstickDown))
            {
                OnButtonDown(Buttons.LeftThumbstickDown);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.LeftThumbstickUp))
            {
                OnButtonDown(Buttons.LeftThumbstickUp);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.LeftThumbstickLeft))
            {
                OnButtonDown(Buttons.LeftThumbstickLeft);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.LeftStick))
            {
                OnButtonDown(Buttons.LeftStick);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            // RightThumbstick Buttons.
            if (IsNewButtonPressed(Buttons.RightThumbstickDown))
            {
                OnButtonDown(Buttons.RightThumbstickDown);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.RightThumbstickUp))
            {
                OnButtonDown(Buttons.RightThumbstickUp);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.RightThumbstickLeft))
            {
                OnButtonDown(Buttons.RightThumbstickLeft);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonPressed(Buttons.RightThumbstickRight))
            {
                OnButtonDown(Buttons.RightThumbstickRight);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            // Shoulder Buttons.
            if (IsNewButtonPressed(Buttons.LeftShoulder))
            {
                OnButtonDown(Buttons.LeftShoulder);
                OnTriggers(m_currentGamePadState.Triggers);
            }

            if (IsNewButtonPressed(Buttons.RightShoulder))
            {
                OnButtonDown(Buttons.RightShoulder);
                OnTriggers(m_currentGamePadState.Triggers);
            }
            #endregion

            #region ButtonUp
            // A Button.
            if (IsNewButtonReleased(Buttons.A))
            {
                OnButtonDown(Buttons.A);
            }

            // B Button.
            if (IsNewButtonReleased(Buttons.B))
            {
                OnButtonDown(Buttons.B);
            }

            // X Button.
            if (IsNewButtonReleased(Buttons.X))
            {
                OnButtonDown(Buttons.X);
            }

            // Y Button.
            if (IsNewButtonReleased(Buttons.Y))
            {
                OnButtonDown(Buttons.Y);
            }

            // Start Button.
            if (IsNewButtonReleased(Buttons.Start))
            {
                OnButtonDown(Buttons.Start);
            }

            // Back Button.
            if (IsNewButtonReleased(Buttons.Back))
            {
                OnButtonDown(Buttons.Back);
            }

            // Big Button.
            if (IsNewButtonReleased(Buttons.BigButton))
            {
                OnButtonDown(Buttons.BigButton);
            }

            // DPadDown Buttons
            if (IsNewButtonReleased(Buttons.DPadDown))
            {
                OnButtonDown(Buttons.DPadDown);
            }


            if (IsNewButtonReleased(Buttons.DPadUp))
            {
                OnButtonDown(Buttons.DPadUp);
            }


            if (IsNewButtonReleased(Buttons.DPadLeft))
            {
                OnButtonDown(Buttons.DPadLeft);
            }

            if (IsNewButtonReleased(Buttons.DPadRight))
            {
                OnButtonDown(Buttons.DPadRight);
            }

            //LeftThumbstick buttons.
            if (IsNewButtonReleased(Buttons.LeftThumbstickDown))
            {
                OnButtonDown(Buttons.LeftThumbstickDown);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.LeftThumbstickUp))
            {
                OnButtonDown(Buttons.LeftThumbstickUp);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.LeftThumbstickLeft))
            {
                OnButtonDown(Buttons.LeftThumbstickLeft);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.LeftThumbstickRight))
            {
                OnButtonDown(Buttons.LeftThumbstickRight);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.LeftThumbstickDown))
            {
                OnButtonDown(Buttons.LeftThumbstickDown);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.LeftThumbstickUp))
            {
                OnButtonDown(Buttons.LeftThumbstickUp);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.LeftThumbstickLeft))
            {
                OnButtonDown(Buttons.LeftThumbstickLeft);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.LeftStick))
            {
                OnButtonDown(Buttons.LeftStick);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            // RightThumbstick Buttons.
            if (IsNewButtonReleased(Buttons.RightThumbstickDown))
            {
                OnButtonDown(Buttons.RightThumbstickDown);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.RightThumbstickUp))
            {
                OnButtonDown(Buttons.RightThumbstickUp);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.RightThumbstickLeft))
            {
                OnButtonDown(Buttons.RightThumbstickLeft);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsNewButtonReleased(Buttons.RightThumbstickRight))
            {
                OnButtonDown(Buttons.RightThumbstickRight);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            // Shoulder Buttons.
            if (IsNewButtonReleased(Buttons.LeftShoulder))
            {
                OnButtonDown(Buttons.LeftShoulder);
                OnTriggers(m_currentGamePadState.Triggers);
            }

            if (IsNewButtonReleased(Buttons.RightShoulder))
            {
                OnButtonDown(Buttons.RightShoulder);
                OnTriggers(m_currentGamePadState.Triggers);
            }
            #endregion

            #region ButtonHeld
            // A Button.
            if (IsButtonPressed(Buttons.A))
            {
                OnButtonHeld(Buttons.A);
            }

            // B Button.
            if (IsButtonPressed(Buttons.B))
            {
                OnButtonHeld(Buttons.B);
            }

            // X Button.
            if (IsButtonPressed(Buttons.X))
            {
                OnButtonHeld(Buttons.X);
            }

            // Y Button.
            if (IsButtonPressed(Buttons.Y))
            {
                OnButtonHeld(Buttons.Y);
            }

            // Start Button.
            if (IsButtonPressed(Buttons.Start))
            {
                OnButtonHeld(Buttons.Start);
            }

            // Back Button.
            if (IsButtonPressed(Buttons.Back))
            {
                OnButtonHeld(Buttons.Back);
            }

            // Big Button.
            if (IsButtonPressed(Buttons.BigButton))
            {
                OnButtonHeld(Buttons.BigButton);
            }

            // DPadDown Buttons
            if (IsButtonPressed(Buttons.DPadDown))
            {
                OnButtonHeld(Buttons.DPadDown);
            }


            if (IsButtonPressed(Buttons.DPadUp))
            {
                OnButtonHeld(Buttons.DPadUp);
            }


            if (IsButtonPressed(Buttons.DPadLeft))
            {
                OnButtonHeld(Buttons.DPadLeft);
            }

            if (IsButtonPressed(Buttons.DPadRight))
            {
                OnButtonHeld(Buttons.DPadRight);
            }

            //LeftThumbstick buttons.
            if (IsButtonPressed(Buttons.LeftThumbstickDown))
            {
                OnButtonHeld(Buttons.LeftThumbstickDown);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.LeftThumbstickUp))
            {
                OnButtonHeld(Buttons.LeftThumbstickUp);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.LeftThumbstickLeft))
            {
                OnButtonHeld(Buttons.LeftThumbstickLeft);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.LeftThumbstickRight))
            {
                OnButtonHeld(Buttons.LeftThumbstickRight);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.LeftThumbstickDown))
            {
                OnButtonHeld(Buttons.LeftThumbstickDown);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.LeftThumbstickUp))
            {
                OnButtonHeld(Buttons.LeftThumbstickUp);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.LeftThumbstickLeft))
            {
                OnButtonHeld(Buttons.LeftThumbstickLeft);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.LeftStick))
            {
                OnButtonHeld(Buttons.LeftStick);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            // RightThumbstick Buttons.
            if (IsButtonPressed(Buttons.RightThumbstickDown))
            {
                OnButtonHeld(Buttons.RightThumbstickDown);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.RightThumbstickUp))
            {
                OnButtonHeld(Buttons.RightThumbstickUp);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.RightThumbstickLeft))
            {
                OnButtonHeld(Buttons.RightThumbstickLeft);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            if (IsButtonPressed(Buttons.RightThumbstickRight))
            {
                OnButtonHeld(Buttons.RightThumbstickRight);
                OnThumbsticks(m_currentGamePadState.ThumbSticks);
            }

            // Shoulder Buttons.
            if (IsButtonPressed(Buttons.LeftShoulder))
            {
                OnButtonHeld(Buttons.LeftShoulder);
                OnTriggers(m_currentGamePadState.Triggers);
            }

            if (IsButtonPressed(Buttons.RightShoulder))
            {
                OnButtonHeld(Buttons.RightShoulder);
                OnTriggers(m_currentGamePadState.Triggers);
            }
            #endregion

        }

        public void AddGamePadHandler(IGamePadHandler gamePadHandler)
        {
            ButtonUp += new GamePadButtonEvent(gamePadHandler.OnButtonUp);
            ButtonDown += new GamePadButtonEvent(gamePadHandler.OnButtonDown);
            ButtonHeld += new GamePadButtonEvent(gamePadHandler.OnButtonHeld);
            Triggers += new GamePadTriggerEvent(gamePadHandler.OnTrigger);
            Thumbsticks += new GamePadThumbstickEvent(gamePadHandler.OnThumbstick);
        }

        public void ClearGamePadHandlers()
        {
            ButtonUp = null;
            ButtonDown = null;
            ButtonHeld = null;
            Triggers = null;
            Thumbsticks = null;
        }
    }
}
